package cn.com.libertymutual.core.web.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import cn.com.libertymutual.core.exception.CustomLangException;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.common.base.Charsets;
import com.google.common.base.Throwables;

/**
 * HttpServletResponse帮助类
 * 
 * @author liufang
 * 
 */
public final class ResponseUtils {
	public static final Logger log = LoggerFactory
			.getLogger(ResponseUtils.class);

	/**
	 * 发送文本。使用UTF-8编码。
	 * 
	 * @param response
	 *            HttpServletResponse
	 * @param text
	 *            发送的字符串
	 * @throws IOException 
	 */
	public static void renderText(HttpServletResponse response, String text) throws IOException {
		render(response, "text/plain;charset=UTF-8", text);
	}

	/**
	 * 发送json。使用UTF-8编码。
	 * 
	 * @param response
	 *            HttpServletResponse
	 * @param text
	 *            发送的字符串
	 * @throws IOException 
	 */
	public static void renderJson(HttpServletResponse response, String text) throws IOException {
		render(response, "application/json;charset=UTF-8", text);
	}

	/**
	 * 发送xml。使用UTF-8编码。
	 * 
	 * @param response
	 *            HttpServletResponse
	 * @param text
	 *            发送的字符串
	 * @throws IOException 
	 */
	public static void renderXml(HttpServletResponse response, String text) throws IOException {
		render(response, "text/xml;charset=UTF-8", text);
	}

	/**
	 * 发送内容。使用UTF-8编码。
	 * 
	 * @param response
	 * @param contentType
	 * @param text
	 * @throws IOException 
	 */
	public static void render(HttpServletResponse response, String contentType,
			String text) throws IOException {
		response.setContentType(contentType);
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		response.getWriter().write(text);
	}
	public static void sendToClient(HttpServletResponse httpResponse, Object result, String charsetName) throws Exception{
		Writer writer = null;
				
		
		
		try {
			if( charsetName == null )
				writer = new OutputStreamWriter(httpResponse.getOutputStream(), Charsets.UTF_8 );
			else writer = new OutputStreamWriter(httpResponse.getOutputStream(), charsetName );
			
			if( result != null && result instanceof String ) {
				writer.write( (String)result );	
			}
			else {
				httpResponse.setContentType("application/json;charset=UTF-8");
				
				/*String json = JSON.toJSONString(result, SerializerFeature.WriteEnumUsingToString,
						SerializerFeature.DisableCircularReferenceDetect);
				httpResponse.setContentType("text/json;charset=UTF-8");
				httpResponse.setContentLength(json.getBytes().length);
				writer = new OutputStreamWriter(httpResponse.getOutputStream(), Charsets.UTF_8);
				log.info(json);*/
				/*log.info(JSON.toJSONString(result, SerializerFeature.WriteEnumUsingToString,
						SerializerFeature.DisableCircularReferenceDetect));*/
				//这个东西无法解析TAB键“\t”
				writer.write(JSON.toJSONString(result, SerializerFeature.WriteEnumUsingToString,
						SerializerFeature.DisableCircularReferenceDetect));
			}
		
		}finally {
			if( writer != null )
				try {
					writer.close();
				//输入输出异常
				} catch (IOException e) {
					Throwables.propagate(new RuntimeException(" HttpServletResponse帮助类,输入输出异常"));
					e.printStackTrace();
				}
		}
	}

	public static void sendToClient(HttpServletResponse httpResponse, Object result ) throws Exception {
		sendToClient(httpResponse, result, null);
	}
	

	public static void sendToClient(Object result ) throws Exception {
		if( result == null ) return;
		
		ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		if( servletRequestAttributes == null ) {
			log.error("获取Response失败，数据{}未发送出去", result);
			return;
		}
		
		HttpServletResponse httpResponse = servletRequestAttributes.getResponse();
		
		sendToClient(httpResponse, result, null);
	}
	public static void download( String fileName, byte[] buff, HttpServletResponse response ) throws IOException {
		setResponseInfo( fileName,  response);
		
		response.setContentLength( steam( buff , response.getOutputStream() ) );
	}
	
	public static void download( String fileName, InputStream in, HttpServletResponse response ) throws IOException {

		setResponseInfo( fileName,  response);
		
		response.setContentLength( steam( in , response.getOutputStream() ) );
	}
	
	private static void setResponseInfo(String fileName, HttpServletResponse response){
		// 修改流的类型为pdf
				// response.setContentType("application/pdf");
				// response.setHeader("Content-type", "application/pdf");
				response.setContentType("application/octet-stream");
				response.setHeader("Content-type", "application/octet-stream");
				response.setHeader("Content-disposition", "attachment;filename=" + fileName);
				// response.setCharacterEncoding("GBK");
				///// fileName = new String(fileName.getBytes("GBK"),
				///// "ISO8859-1");
				// 修改流的类型为pdf

				// 这个的添加也是因为影响到了打印
				response.setHeader("Accept-Ranges", "bytes");

				response.setHeader("Pragma", "No-cache");
				response.setHeader("Cache-Control", "no-cache");
				// response.setHeader("Content-type",
				// "application/octet-stream");
				//response.setContentLength(in.available());
	}

	public static void download( File localFile, HttpServletResponse response ) throws IOException {

		InputStream input = new FileInputStream( localFile );
		
		download( localFile.getName(), input, response);
	}
	
	/**
	 * 输出
	 * 
	 * @param is
	 * @param os
	 * @throws CustomLangException
	 */
	public static int steam(InputStream is, OutputStream os) throws CustomLangException {

		int ret = 0;
		byte[] buffer = new byte[1024];
		int length = 0;
		try {
			while ((length = is.read(buffer)) > 0) {
				ret += length;
				os.write(buffer, 0, length);
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			// 将捕获到的异常转换为自定义异常抛出
			throw new CustomLangException(e);
		} finally {
			try {
				os.close();
				is.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}

		return ret;
	}
	/**
	 * 输出
	 * 
	 * @param is
	 * @param os
	 * @throws CustomLangException
	 */
	public static int steam(byte[] buffer , OutputStream os) throws CustomLangException {
		
		int ret =buffer.length;
		try {
			os.write(buffer);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			// 将捕获到的异常转换为自定义异常抛出
			throw new CustomLangException(e);
		} finally {
			try {
				os.close();
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}

		return ret;
	}
}
